package com.wind.plugin.rule;

import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiFile;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import org.jetbrains.annotations.NotNull;

import static com.wind.plugin.common.Common.shouldSkipCheck;
import static com.wind.plugin.window.Utils.containsMissingInsertImcustNo;
import static com.wind.plugin.window.Utils.containsMissingWhereImcustNo;


/**
 * 功能描述：针对xml文件中sql语句进行自定义校验
 */
public class MapperCheckRule extends LocalInspectionTool {


    /**
     * 重写buildVisitor方法实现代码检查
     * @param holder holder
     * @param isOnTheFly
     * @return
     */
    @NotNull
    @Override
    public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
        /**IDEA中将每一个文件都认为是PSI,PSI中的元素为PSI element
         * PsiElementVisitor 对象，用于遍历被检查文件的 PSI 树。
         * */
        return new PsiElementVisitor() {
            /**遍历PSI File*/
            @Override
            public void visitFile(PsiFile file) {
                super.visitFile(file);
                /**检查文件是否为 XML 文件并且文件名符合条件*/
                if (file instanceof XmlFile && file.getName().matches(".*\\.xml")) {
                    /** 获取文件的根元素 */
                    XmlTag rootTag = ((XmlFile) file).getRootTag();
                    /** 递归检查所有子元素 */
                    if (rootTag != null) {
                        checkXmlTag(rootTag, holder);
                    }
                }
            }

            // 递归检查 XML 标签及其子标签
            private void checkXmlTag(XmlTag tag, ProblemsHolder holder) {
                // 检查标签前是否有注释
                if (shouldSkipCheck(tag)) {
                    return;
                }
                // 检查当前标签是否为 select 标签
                if ("select".equalsIgnoreCase(tag.getName()) || "update".equalsIgnoreCase(tag.getName())
                 || "delete".equalsIgnoreCase(tag.getName())) {
                    // 获取 标签中的文本内容
                    String text = tag.getValue().getText();
                    // 检查文本内容是否包含 "im_cust_no"
                    if (!containsMissingWhereImcustNo(text)) {
                        // 在文本内容中不包含 "im_cust_no" 时添加警告
                        holder.registerProblem(tag,
                                "SQL语句where条件中丢失了im_cust_no字段。",
                                ProblemHighlightType.WEAK_WARNING);
                    }
                }
                if ("insert".equalsIgnoreCase(tag.getName())) {
                    // 获取 标签中的文本内容
                    String text = tag.getValue().getText();

                    // 检查文本内容是否包含 "im_cust_no"
                    if (!containsMissingInsertImcustNo(text)) {
                        // 在文本内容中不包含 "im_cust_no" 时添加警告
                        holder.registerProblem(tag,
                                "SQL语句insert条件中丢失了im_cust_no字段。",
                                ProblemHighlightType.WEAK_WARNING);
                    }
                }

                // 递归检查子标签
                for (XmlTag child : tag.getSubTags()) {
                    checkXmlTag(child, holder);
                }
            }
        };
    }

}
